#    Copyright 2008, 2009 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPGIS.
#    COOPGIS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPGIS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPGIS.  If not, see <http://www.gnu.org/licenses/>.

import os
import datetime
FTPFileName='/opt/coopgis/fromgps/anonymousftproot_OtherReadOnly/incomingftpallpermissions/Locations.csv'
import shutil

#************************BEGIN Add Include Files to Path************************
import sys
NeededPaths=['/opt/coopgis/djangoproject/include', '/opt/coopgis/djangoproject']
for path in NeededPaths:
    if(not path in sys.path):
        sys.path.append(path)
#************************END   Add Include Files to Path************************
from django.contrib.gis.geos import *
import os, time, psycopg2, datetime
#********************Setup psycopg2 and django section********************
PathDjangoRoot="/opt/coopgis/"
if(not PathDjangoRoot in sys.path):
    sys.path.append(PathDjangoRoot)

import djangoproject
from djangoproject import settings
from djangoproject.models import *
#********************Setup psycopg2 and django section********************
import COOPGIS_Ajax, COOPGIS_GPS, COOPGIS_Misc, COOPGIS_ReportLab, COOPGIS_String, COOPGIS_Update
from django.template import Context, loader
from django.http import HttpResponse
from django import forms
import os
import datetime
import djangoproject.settings
import reportlab
import Image



def Create(stakerWorkOrder, MapFileName):
    """Creates a PDF Report of the current StakerWork Order with an Image from MapServer, uses ReportLab"""
    GlobalStakerWorkOrder[0]=stakerWorkOrder
    GlobalMapFileName[0]=MapFileName
    StakerWorkOrderid[0]=str(stakerWorkOrder.id)
    djangoproject.models.ReportPageNumberPolygon.objects.filter(MapReportIdentifier=StakerWorkOrderid[0]).delete()
    doc = MyDocTemplate(stakerWorkOrder.GetReportFileName())
    doc.pagesize=reportlab.lib.pagesizes.landscape(reportlab.lib.pagesizes.LEGAL)
    doc.leftMargin = 0.27 * reportlab.lib.units.inch
    doc.rightMargin=0.27 * reportlab.lib.units.inch
    doc.topMargin=0.27 * reportlab.lib.units.inch
    doc.bottomMargin=0.27 * reportlab.lib.units.inch
    #Story=[reportlab.platypus.Spacer(1, 2*reportlab.lib.units.inch)]
    Story=[]  
    #styles=reportlab.lib.styles.getSampleStyleSheet()
    #style=styles["Normal"]
    Story.append(reportlab.platypus.Spacer(0, 2.25*reportlab.lib.units.inch))

    Story.append(BuildSummaryTable(stakerWorkOrder))
    Story.append(reportlab.platypus.NextPageTemplate('rest'))
    Tables=BuildTable(stakerWorkOrder)
    for t in Tables:
        Story.append(t)
        if(not t == Tables[-1]):
            Story.append(reportlab.platypus.PageBreak())
    Story.append(reportlab.platypus.NextPageTemplate('last'))
    Story.append(reportlab.platypus.Spacer(0, 7*reportlab.lib.units.inch))

    LastPageNumber = COOPGIS_ReportLab.LastPageNumberFlowable(13.65 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch)
    Story.append(LastPageNumber)
    try:
        os.remove(stakerWorkOrder.GetReportFileName())
    except:
        pass
    doc.StakerWorkOrder=stakerWorkOrder
    doc.build(Story)
    djangoproject.models.ReportPageNumberPolygon.objects.filter(MapReportIdentifier=StakerWorkOrderid[0]).delete()

def BuildSummaryTable(stakerWorkOrder):
    Data=stakerWorkOrder.GetStakerSummary()
    colWidths=[2.5*reportlab.lib.units.inch,1*reportlab.lib.units.inch,1*reportlab.lib.units.inch]*3
    Headings=['', 'Install', 'Remove']
    OHPrimary=['Overhead Primary Wire Footage', Data['OverheadPrimaryWireFootageInstall'], Data['OverheadPrimaryWireFootageRemove']]
    OHSecondary=['Overhead Secondary Wire Footage', Data['OverheadSecondaryWireFootageInstall'], Data['OverheadSecondaryWireFootageRemove']]
    OHService=['Overhead Service Wire Footage', Data['OverheadServiceWireFootageInstall'], Data['OverheadServiceWireFootageRemove']]
    UGPrimary=['Underground Primary Wire Footage', Data['UndergroundPrimaryWireFootageInstall'], Data['UndergroundPrimaryWireFootageRemove']]
    UGSecondary=['Underground Secondary Wire Footage', Data['UndergroundSecondaryWireFootageInstall'], Data['UndergroundSecondaryWireFootageRemove']]
    UGService=['Underground Service Wire Footage', Data['UndergroundServiceWireFootageInstall'], Data['UndergroundServiceWireFootageRemove']]
    Lights=['Number of Security Lights', Data['NumberOfSecurityLightsInstall'], Data['NumberOfSecurityLightsRemove']]
    Transformers=['Number of Transformers', Data['NumberOfTransformersInstall'], Data['NumberOfTransformersRemove']]
    Blank=['', '', '']
    TableData=[Headings*3, OHPrimary + UGPrimary + Lights, OHSecondary + UGSecondary + Transformers, OHService + UGService + Blank]
    t=reportlab.platypus.Table(TableData, colWidths=colWidths)
    return t


def StakerReportCheckDistanceBetweenStations(PreviousRow, CurrentRow):
    """Checks to see whether the stations that would appear in the specified rows are more than a certain distance apart
       If so, returns True so a page break can be added, otherwise returns False"""
    PreviousStation=djangoproject.models.geography.Station.objects.filter(id=int(PreviousRow[0]))[0]
    CurrentStation=djangoproject.models.geography.Station.objects.filter(id=int(CurrentRow[0]))[0]
    if(PreviousStation.Point.distance(CurrentStation.Point) > 3000):
        return True
    else:
        return False

def BuildTable(stakerWorkOrder):
    WidthLocation=0.46*reportlab.lib.units.inch
    WidthPole=1.08*reportlab.lib.units.inch
    WidthSpanPrimary=0.40*reportlab.lib.units.inch
    WidthSpanIDPrimary=0.5*reportlab.lib.units.inch
    WidthUnitPrimary=0.75*reportlab.lib.units.inch
    WidthConductorPrimary=1.31*reportlab.lib.units.inch
    WidthTransformer=0.95*reportlab.lib.units.inch
    WidthMisc=1.32*reportlab.lib.units.inch
    WidthGround=0.74*reportlab.lib.units.inch
    WidthGuy=0.65*reportlab.lib.units.inch
    WidthAnchorMarker=0.63*reportlab.lib.units.inch
    WidthSpanSecondary=0.69*reportlab.lib.units.inch  
    WidthSpanIDSecondary=0.5*reportlab.lib.units.inch
    WidthUnitSecondary=0.82*reportlab.lib.units.inch 
    WidthConductorSecondary=1.12*reportlab.lib.units.inch
    WidthComment=1.69*reportlab.lib.units.inch
    colWidths=[WidthLocation, WidthPole, WidthSpanPrimary, WidthSpanIDPrimary, WidthConductorPrimary, WidthUnitPrimary, 
               WidthTransformer, WidthMisc, WidthGround,
               WidthGuy, WidthAnchorMarker, WidthSpanSecondary, WidthSpanIDSecondary, WidthConductorSecondary, WidthUnitSecondary,  WidthComment]
    PreHeadingRow=['PoleID', 'Pole H/C', 'Primary','', '', '', 'Transformer', 'Misc Equipment',
                   'Ground', 'Guy', '', 'Secondary/Service', '',  '', '', 'Comments']
    HeadingRow=['','','Span', 'SpanID', 'Conductor','Unit','','','',
                'Guy', 'Anchor/\nMarker', 'Span', 'SpanID', 'Conductor','Unit', '']
    data=GetTableData(stakerWorkOrder)
    FirstRow=True
    Tables=[[]]
    Tables[0].append(PreHeadingRow)
    Tables[0].append(HeadingRow)

    for row in data:
        Current=row
        PageBreakIndicator=False
        if(FirstRow):
            FirstRow=False
        else:
            PageBreakIndicator=StakerReportCheckDistanceBetweenStations(Previous, Current)
        if(PageBreakIndicator): 
            Tables.append([])
            Tables[-1].append(PreHeadingRow)
            Tables[-1].append(HeadingRow)

        Tables[-1].append(row)
        Previous=row
    #Tables is now a list of tables, the 1st needs to be formatted with headings, the later ones should appear at the start of new pages
    #formatted in the proper way
    t = []
    t.append(reportlab.platypus.Table(Tables[0], colWidths=colWidths))
    t[0].repeatRows=2
    t[0].setStyle(reportlab.platypus.TableStyle([
                            ('BACKGROUND',(0,0),(len(HeadingRow)-1, 1),reportlab.lib.colors.lightgrey),
                            ('FONT',(0,0), (len(HeadingRow)-1, 1), 'Times-Bold', 10),#Heading Rows Font
                            ('FONT',(0,2), (len(HeadingRow)-1, -1), 'Times-Roman', 7), #Rest of Table Font
                            ('TEXTCOLOR',(0,0),(1,-1),reportlab.lib.colors.black),
                            ('BOX', (0,0), (-1,-1), 0.20, reportlab.lib.colors.black),
                            ('INNERGRID',(0,0), (-1,-1), 0.20, reportlab.lib.colors.black),
                            #The Following 'SPAN' Lines combine boxes of the report on an X,Y Grid so they lose their interior borders
                            ('SPAN', (0,1),(0,0)), #Location
                            ('SPAN', (1,1),(1,0)), #Pole H/C
                            ('SPAN', (2,0),(5,0)), #Primary
                            ('SPAN', (6,1),(6,0)), #Transformer
                            ('SPAN', (7,1),(7,0)), #Misc Equipment
                            ('SPAN', (8,1),(8,0)), #Ground
                            ('SPAN', (9,0),(10,0)), #Guy
                            ('SPAN', (11,0),(14,0)), #Secondary/Service
                            ('SPAN', (15,1),(15,0)), #Comments
                            ('ALIGN', (0,0), (len(HeadingRow)-1,1),'CENTER'), #Center Heading Rows
                            ('VALIGN', (0,1), (-1, -1), "TOP"), #Align Data to top of cells
                            ('BOTTOMPADDING', (0,1), (len(HeadingRow)-2, -1), reportlab.lib.units.inch * 0.25),  #Allow Comments Column to go to the bottom
                            ]))
    if(len(Tables) == 1):
        return t
    Count = 1
    for i in Tables[1:]:
        t.append(reportlab.platypus.Table(i, colWidths=colWidths))
        t[Count].repeatRows=2
        t[Count].setStyle(reportlab.platypus.TableStyle([
                            ('BACKGROUND',(0,0),(len(HeadingRow)-1, 1),reportlab.lib.colors.lightgrey),
                            ('FONT',(0,0), (len(HeadingRow)-1, 1), 'Times-Bold', 10),#Heading Rows Font
                            ('FONT',(0,2), (len(HeadingRow)-1, -1), 'Times-Roman', 7), #Rest of Table Font
                            ('TEXTCOLOR',(0,0),(1,-1),reportlab.lib.colors.black),
                            ('BOX', (0,0), (-1,-1), 0.20, reportlab.lib.colors.black),
                            ('INNERGRID',(0,0), (-1,-1), 0.20, reportlab.lib.colors.black),
                            #The Following 'SPAN' Lines combine boxes of the report on an X,Y Grid so they lose their interior borders
                            ('SPAN', (0,1),(0,0)), #Location
                            ('SPAN', (1,1),(1,0)), #Pole H/C
                            ('SPAN', (2,0),(5,0)), #Primary
                            ('SPAN', (6,1),(6,0)), #Transformer
                            ('SPAN', (7,1),(7,0)), #Misc Equipment
                            ('SPAN', (8,1),(8,0)), #Ground
                            ('SPAN', (9,0),(10,0)), #Guy
                            ('SPAN', (11,0),(14,0)), #Secondary/Service
                            ('SPAN', (15,1),(15,0)), #Comments
                            ('ALIGN', (0,0), (len(HeadingRow)-1,1),'CENTER'), #Center Heading Rows
                            ('VALIGN', (0,1), (-1, -1), "TOP"), #Align Data to top of cells
                            ('BOTTOMPADDING', (0,1), (len(HeadingRow)-2, -1), reportlab.lib.units.inch * 0.25),  #Allow Comments Column to go to the bottom
                            ]))
        Count = Count + 1
    return t

def GetTableData(stakerWorkOrder, SkipColors=False):
    """Returns 15 Columns of Data in a list of lists:
    StationID, Pole H/C, SpanPrimary, UnitPrimary, ConductorPrimary, Transformer, Misc Equipment, Ground,
    GuyGuy, AnchorGuy, MarkerGuy, SpanSecondary, UnitSecondary, ConductorSecondary, MeterSecondary, Comments"""
    #StationSpanList is a List in the format [station, span1, span2, span3, span4...]
    StationSpanList=stakerWorkOrder.GetOrderedStationSpanList()
    Data=[]
    AlreadyAssignedSpanAssemblies=[]  #Span Assemblies that have already been put into a station on the report
    StationsAlreadyStaked=[]
    for row in StationSpanList:
        station=row[0]
        Spans=row[1:]
        TempRow=[]
        TaggedStationid=PA.onDrawStr(str(station.id), str(station.id))
        TempRow.append(TaggedStationid)
        TempRow.append(AddColorsToString(GetPoleText(stakerWorkOrder, station), SkipColors=SkipColors))
        TempRowConductorPrimary, TempRowSpanIDPrimary, TempRowSpanPrimary=GetConductorPrimaryText(stakerWorkOrder, Spans, AlreadyAssignedSpanAssemblies, StationsAlreadyStaked)
        TempRow.append(AddColorsToString(TempRowSpanPrimary, TempRowConductorPrimary, SkipColors=SkipColors))
        TempRow.append(AddColorsToString(TempRowSpanIDPrimary, TempRowConductorPrimary, SkipColors=SkipColors)) 
        TempRow.append(AddColorsToString(TempRowConductorPrimary, SkipColors=SkipColors))
        TempRow.append(AddColorsToString(GetFramingPrimaryText(stakerWorkOrder, station), SkipColors=SkipColors))
        TempRow.append(AddColorsToString(GetTransformerText(stakerWorkOrder, station), SkipColors=SkipColors))
        TempRow.append(AddColorsToString(GetMiscEquipmentText(stakerWorkOrder, station, AlreadyAssignedSpanAssemblies), SkipColors=SkipColors))
        TempRow.append(AddColorsToString(GetGroundText(stakerWorkOrder, station), SkipColors=SkipColors))
        TempRow.append(AddColorsToString(GetGuyGuyText(stakerWorkOrder, station), SkipColors=SkipColors))
        TempRow.append(AddColorsToString(GetGuyAnchorMarkerText(stakerWorkOrder, station), SkipColors=SkipColors))
        TempRowConductorSecondary, TempRowSpanIDSecondary, TempRowSpanSecondary=GetConductorSecondaryText(stakerWorkOrder, Spans, AlreadyAssignedSpanAssemblies, StationsAlreadyStaked)
        TempRow.append(AddColorsToString(TempRowSpanSecondary, TempRowConductorSecondary, SkipColors=SkipColors))
        TempRow.append(AddColorsToString(TempRowSpanIDSecondary, TempRowConductorSecondary, SkipColors=SkipColors)) 
        TempRow.append(AddColorsToString(TempRowConductorSecondary, SkipColors=SkipColors))
        TempRow.append(AddColorsToString(GetFramingSecondaryText(stakerWorkOrder, station), SkipColors=SkipColors))
        TempRow.append(Columnize(str(station.Description)))
        Data.append(TempRow)
        StationsAlreadyStaked.append(station)
    return Data

def Columnize(String, ColumnLength = 29):
    StringAsWordList=String.split()
    StringAsWordList.append('')
    CurrentPartialLine=[]
    CurrentLineLength = 0
    Results=[]
    for word in StringAsWordList:
        if(len(word) + CurrentLineLength) < ColumnLength:
            CurrentPartialLine.append(word)
            CurrentLineLength = CurrentLineLength + len(word) + 1
        elif(len(word) < ColumnLength):
            Results.append(' '.join(CurrentPartialLine))
            Results.append('\n')
            CurrentLineLength = 0
            CurrentPartialLine = []
            CurrentPartialLine.append(word)
            CurrentLineLength=CurrentLineLength + len(word)
        else: #Meaning that the len of the current word is ColumnLength or greater
            if(CurrentPartialLine):
                for i in CurrentPartialLine:
                    Results.append(' '.join(CurrentPartialLine))
                    CurrentPartialLine=[]
                Results.append('\n')
                CurrentLineLength=0
            temp = []
            tempcount=0
            for i in word:
                temp.append(i)
                tempcount = tempcount + 1
                if(tempcount % ColumnLength == 0):
                    temp.append('\n')
            if(tempcount % ColumnLength != 0):
                temp.append('\n')
            TempString=''.join(temp)
            Results.append(TempString)
    Results.append(' '.join(CurrentPartialLine))
    return ''.join(Results)

def AddColorsToString(string, ComparisonString=None, SkipColors=False):
    if(SkipColors):
        return string
    if(not ComparisonString):  
        ComparisonString=string  #ComparisonString allows strings without (I) or (E) to be colored based on another string
    NormalStyle=reportlab.lib.styles.getSampleStyleSheet()['Normal']
    rows=string.split('\n')
    ComparisonRows=ComparisonString.split('\n')
    i = 0
    for i in range(0, len(rows)):
        if(ComparisonRows[i].find('(I)-') > -1):
            rows[i] = '<font face="Times-Roman" size="7.5" color="blue">' + rows[i] + '</font><br/>'
        elif(ComparisonRows[i].find('(R)-') > -1):
            rows[i] = '<font face="Times-Roman" size="7.5" color="darkred">' + rows[i] + '</font><br/>' 
        else:
            rows[i] = '<font face="Times-Roman" size="7.5" color="black">' + rows[i] + '</font><br/>'
    string = '\n'.join(rows)
    return reportlab.platypus.Paragraph(string, NormalStyle)

def GetPrependInstallStatus(stakerWorkOrder, assembly):
    if(assembly.StakerWorkOrder == stakerWorkOrder or assembly.InstallStatus.Name == 'Existing'):
        return '(' + assembly.InstallStatus.Name[0] + ')-'
    if(assembly.InstallStatus.Name == 'Install'):
        return '(FI)-'
    if(assembly.InstallStatus.Name == 'Remove'):
        return '(FR)-'

def OrderByInstallStatus(Assemblies):
    Results=[]
    InstallStatuses=InstallStatus.objects.all().order_by('StakerReportOrder')
    for installStatus in InstallStatuses:
        for assembly in Assemblies:
            if(assembly.InstallStatus==installStatus):
              Results.append(assembly)
    return Results

def GetPoleText(stakerWorkOrder, station): 
    Poles=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerPoleIndicator=True))
    Temp=[]
    for i in Poles:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i) + ' #' + str(i.TagNumber))
    Temp=CombineLikeEquipment(Temp)
    return '\n'.join(Temp)

def GetFramingPrimaryText(stakerWorkOrder, station):
    FramingsPrimary=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerUnitIndicator=True).exclude(SecondaryIndicator=True).exclude(ServiceIndicator=True))  
    Temp=[]
    for i in FramingsPrimary:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    Temp=CombineLikeEquipment(Temp)
    return '\n'.join(Temp)

def GetConductorPrimaryText(stakerWorkOrder, Spans, AlreadyAssignedSpanAssemblies, StationsAlreadyStaked):
    Temp=[]
    TempSpanID=[]
    TempSpan=[]
    for span in Spans:
        PrimaryConductors=OrderByInstallStatus(Assembly.objects.filter(Span=span).filter(CompatibleUnit__StakerSpanAssemblyIndicator=True))    
        for conductor in PrimaryConductors:
            if(not conductor.SecondaryIndicator and not conductor.ServiceIndicator):  #Primary Wire used for non-primary purposes must appear w/ secondary/service
                if(not conductor in AlreadyAssignedSpanAssemblies):
                   AlreadyAssignedSpanAssemblies.append(conductor)
                else:
                    continue
                Temp.append(GetPrependInstallStatus(stakerWorkOrder, conductor) + str(conductor))
                TempSpanID.append(str(conductor.Span.id))
                TempSpan.append(str(int(round(conductor.Span.GetLength(),0))))
    Temp, TempSpanID, TempSpan = CombineLikeConductors(Temp, TempSpanID, TempSpan)
    return '\n'.join(Temp), '\n'.join(TempSpanID), '\n'.join(TempSpan)

def CombineLikeEquipment(AssemblyList, StationForPhase=None):
    NewAssemblyList=[]
    UniqueAssemblies=[]
    for i in range(0, len(AssemblyList)):
        CountOfCurrentAssembly=0
        for j in range(0, len(AssemblyList)):
            if(AssemblyList[i] == AssemblyList[j]):
                CountOfCurrentAssembly = CountOfCurrentAssembly + 1
        if(not AssemblyList[i] in UniqueAssemblies):
            UniqueAssemblies.append(AssemblyList[i])
            NewAssemblyList.append(str(CountOfCurrentAssembly) + '-' + str(AssemblyList[i]))
    if(StationForPhase):
        for i in range(0, len(NewAssemblyList)):
            CurrentAssemblyNameWithExtraInformation=NewAssemblyList[i]
            CurrentAssemblyNameStartOffset=CurrentAssemblyNameWithExtraInformation.find('(I)-') 
            if(not CurrentAssemblyNameStartOffset == -1):  #Add the Install Phase Code Strings
                CurrentAssemblyName=CurrentAssemblyNameWithExtraInformation[CurrentAssemblyNameStartOffset + len('(I)-'):]
                CurrentAssemblies=Assembly.objects.filter(Station=StationForPhase).filter(CompatibleUnit__Name=CurrentAssemblyName).filter(InstallStatus__Name='Install')
                PhaseCodeString=' [' + CurrentAssemblies[0].GetSumOfPhaseCodes(CurrentAssemblies) + ']'
                if(not (PhaseCodeString == ' []')):    
                    NewAssemblyList[i] = NewAssemblyList[i] + PhaseCodeString
            CurrentAssemblyNameStartOffset=CurrentAssemblyNameWithExtraInformation.find('(E)-') 
            if(not CurrentAssemblyNameStartOffset == -1):  #Add the Existing Phase Code Strings
                CurrentAssemblyName=CurrentAssemblyNameWithExtraInformation[CurrentAssemblyNameStartOffset + len('(E)-'):]
                CurrentAssemblies=Assembly.objects.filter(Station=StationForPhase).filter(CompatibleUnit__Name=CurrentAssemblyName).filter(InstallStatus__Name='Existing')
                PhaseCodeString=' [' + CurrentAssemblies[0].GetSumOfPhaseCodes(CurrentAssemblies) + ']'
                if(not (PhaseCodeString == ' []')):    
                    NewAssemblyList[i] = NewAssemblyList[i] + PhaseCodeString
            CurrentAssemblyNameStartOffset=CurrentAssemblyNameWithExtraInformation.find('(R)-') 
            if(not CurrentAssemblyNameStartOffset == -1):  #Add the Remove Phase Code Strings
                CurrentAssemblyName=CurrentAssemblyNameWithExtraInformation[CurrentAssemblyNameStartOffset + len('(R)-'):]
                CurrentAssemblies=Assembly.objects.filter(Station=StationForPhase).filter(CompatibleUnit__Name=CurrentAssemblyName).filter(InstallStatus__Name='Remove')
                PhaseCodeString=' [' + CurrentAssemblies[0].GetSumOfPhaseCodes(CurrentAssemblies) + ']'
                if(not (PhaseCodeString == ' []')):    
                    NewAssemblyList[i] = NewAssemblyList[i] + PhaseCodeString
    return NewAssemblyList

def GetTransformerText(stakerWorkOrder, station):
    Transformers=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerTransformerIndicator=True))
    Temp=[]
    CombineIndicator=True
    for i in Transformers:
        if(i.TagNumber):
            Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i)  + ' #' + str(i.TagNumber))
            CombineIndicator=False
        else:
            Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    if(CombineIndicator):
        Temp=CombineLikeEquipment(Temp, StationForPhase=station)
    return '\n'.join(Temp)

def GetMiscEquipmentText(stakerWorkOrder, station, AlreadyCollectedSpanAssemblies):
    #First get the Conduit [eliminate Trench Indicator field and combine???]
    Span1=Span.objects.filter(StartStation=station)
    Span2=Span.objects.filter(EndStation=station)
    Spans=[]
    for span in Span1:
        Spans.append(span)
    for span in Span2:
        Spans.append(span)
    Temp=[]
    MiscEquipments=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerMiscEquipmentIndicator=True))
    for assembly in MiscEquipments:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, assembly) + str(assembly))
    Temp=CombineLikeEquipment(Temp, StationForPhase=station)
    return '\n'.join(Temp)

def GetGroundText(stakerWorkOrder, station):
    Grounds=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerGroundIndicator=True))
    Temp=[]
    for i in Grounds:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    Temp=CombineLikeEquipment(Temp)
    return '\n'.join(Temp)

def GetGuyGuyText(stakerWorkOrder, station):
    GuysGuy=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerGuyGuyIndicator=True))
    Temp=[]
    for i in GuysGuy:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    Temp=CombineLikeEquipment(Temp)
    return '\n'.join(Temp)

def GetGuyAnchorMarkerText(stakerWorkOrder, station):
    Temp=[]
    AnchorsGuy=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerGuyAnchorIndicator=True))
    for i in AnchorsGuy:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    GuyMarkers=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerGuyMarkerIndicator=True))
    for i in GuyMarkers:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    Temp=CombineLikeEquipment(Temp)
    return '\n'.join(Temp)

def GetConductorSecondaryText(stakerWorkOrder, Spans, AlreadyAssignedSpanAssemblies, StationsAlreadyStaked):
    Temp=[]
    TempSpanID=[]
    TempSpan=[]
    for span in Spans:
        SecondaryConductors=OrderByInstallStatus(Assembly.objects.filter(Span=span).filter(CompatibleUnit__StakerSpanAssemblyIndicator=True).filter(SecondaryIndicator=True))    
        ServiceConductors=OrderByInstallStatus(Assembly.objects.filter(Span=span).filter(CompatibleUnit__StakerSpanAssemblyIndicator=True).filter(ServiceIndicator=True))
        AllSpanAssemblies=[]
        for conductor in SecondaryConductors:
            AllSpanAssemblies.append(conductor)
        for conductor in ServiceConductors:
            if(not conductor in AllSpanAssemblies):
                AllSpanAssemblies.append(conductor)
        for conductor in AllSpanAssemblies:
            if(not conductor.PrimaryIndicator and not conductor in AlreadyAssignedSpanAssemblies):
                AlreadyAssignedSpanAssemblies.append(conductor)
                Temp.append(GetPrependInstallStatus(stakerWorkOrder, conductor) + str(conductor))
                TempSpanID.append(str(conductor.Span.id))
                TempSpanPostfix=''
                if(conductor.ServiceIndicator):
                    TempSpanPostfix=' SVC'
                elif(conductor.SecondaryIndicator):
                    TempSpanPostfix=' SEC'
                TempSpan.append(str(int(round(conductor.Span.GetLength(),0))) + TempSpanPostfix)
    Temp, TempSpanID, TempSpan = CombineLikeConductors(Temp, TempSpanID, TempSpan)
    return '\n'.join(Temp), '\n'.join(TempSpanID), '\n'.join(TempSpan)

def GetFramingSecondaryText(stakerWorkOrder, station):
    FramingsSecondary=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerUnitIndicator=True).filter(SecondaryIndicator=True))
    Temp=[]
    for i in FramingsSecondary:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    FramingsService=OrderByInstallStatus(Assembly.objects.filter(Station=station).filter(CompatibleUnit__StakerUnitIndicator=True).filter(ServiceIndicator=True))
    for i in FramingsService:
        Temp.append(GetPrependInstallStatus(stakerWorkOrder, i) + str(i))
    Temp=CombineLikeEquipment(Temp)
    return '\n'.join(Temp)



def CheckBox(canvas, Corner, CheckStatus):
    Width=0.1*reportlab.lib.units.inch
    Height=0.1*reportlab.lib.units.inch
    canvas.rect(Corner[0], Corner[1], Width, Height)
    if(CheckStatus == 'True'):
        CheckStatus=True
    if(CheckStatus == 'False'):
        CheckStatus=False
    if(bool(CheckStatus)):
        canvas.line(Corner[0], Corner[1], Corner[0] + Width, Corner[1] + Height)
        canvas.line(Corner[0] + Width, Corner[1], Corner[0], Corner[1] + Height)

def TopLeftRectangle(stakerWorkOrder, canvas):
    FirstPageInfo={}
    FirstPageInfo['PAGE_HEIGHT'] = reportlab.lib.pagesizes.LEGAL[0]
    FirstPageInfo['PAGE_WIDTH'] = reportlab.lib.pagesizes.LEGAL[1]
    Corner=[0.18*reportlab.lib.units.inch, FirstPageInfo['PAGE_HEIGHT'] - 2.25 * reportlab.lib.units.inch]
    Height = 1.9 * reportlab.lib.units.inch
    Width = 3.1 * reportlab.lib.units.inch
    ExtensionWidth=1.5 * reportlab.lib.units.inch
    ExtensionHeight=0.53  * reportlab.lib.units.inch
    canvas.line(Corner[0], Corner[1], Corner[0]+Width, Corner[1]) #Top of Rectangle
    canvas.line(Corner[0]+Width, Corner[1] + Height, Corner[0]+Width+ExtensionWidth, Corner[1] + Height) #Top of Extension, Bottom of extension is neighboring rectangle
    canvas.line(Corner[0]+Width+ExtensionWidth, Corner[1] + Height, Corner[0]+Width+ExtensionWidth, Corner[1] + Height - ExtensionHeight) #Side of Extension

    canvas.line(Corner[0]+Width, Corner[1] + Height - ExtensionHeight, Corner[0]+Width, Corner[1]) 
    canvas.line(Corner[0]+Width, Corner[1]+Height, Corner[0], Corner[1]+Height)
    canvas.line(Corner[0], Corner[1]+Height, Corner[0], Corner[1]) 

    #canvas.rect(Corner[0], Corner[1], Width, Height) 
    dx = 0.25 * reportlab.lib.units.inch
    dy = 0.15 * reportlab.lib.units.inch
    canvas.drawString(Corner[0] + dx, Corner[1] + dy / 2, "CHECK WHERE SEPTIC TANK IS")
    CheckBox(canvas, (Corner[0] + dx / 4, Corner[1] + dy / 2), stakerWorkOrder.CheckWhereSepticTankIsIndicator) 
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 1.5, "TAILGATE DISCUSSION")
    CheckBox(canvas, (Corner[0] + dx / 4, Corner[1] + dy * 1.5), stakerWorkOrder.TailgateDiscussionIndicator) 
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 2.5, "PPE REQUIREMENTS")
    CheckBox(canvas, (Corner[0] + dx / 4, Corner[1] + dy * 2.5), stakerWorkOrder.PPERequirementsIndicator) 
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 3.5, "ENERGY SOURCE CONTROLS")
    CheckBox(canvas, (Corner[0] + dx / 4, Corner[1] + dy * 3.5), stakerWorkOrder.EnergySourceControlsIndicator) 
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 4.5, "SPECIAL PRECAUTIONS")
    CheckBox(canvas, (Corner[0] + dx / 4, Corner[1] + dy * 4.5), stakerWorkOrder.SpecialPrecautionsIndicator) 
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 5.5, "WORK PROCEDURE INVOLVED")
    CheckBox(canvas, (Corner[0] + dx / 4, Corner[1] + dy * 5.5), stakerWorkOrder.WorkProcedureInvolvedIndicator) 
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 6.5, "HAZARDS ASSOCIATED WITH JOB")
    CheckBox(canvas, (Corner[0] + dx / 4, Corner[1] + dy * 6.5), stakerWorkOrder.HazardsAssociatedWithJobIndicator) 
    canvas.drawString(Corner[0] + dx / 4, Corner[1] + (Height - dy * 1.25), "Date Completed:")
    canvas.drawString(Corner[0] + dx / 4 + (4*dx), Corner[1] + (Height - dy * 1.25), "_______________")
    canvas.drawString(Corner[0] + dx / 4 + (0*dx), Corner[1] + (Height - dy * 3.25), "By:")
    canvas.drawString(Corner[0] + dx / 4 + (1*dx), Corner[1] + (Height - dy * 3.25), "______________")
    canvas.drawString(Corner[0] + dx / 4 + (0*dx), Corner[1] + (Height - dy * 4.75), "Initials:  ____    ____    ____    ____")

    canvas.drawString(Corner[0] + Width + dx / 4 + (-2*dx), Corner[1] + (Height - dy * 1.25), "Start Time:")
    canvas.drawString(Corner[0] + Width + dx / 4 + (2*dx), Corner[1] + (Height - dy * 1.25), "______________")

    canvas.drawString(Corner[0] + Width + dx / 4 + (-2*dx), Corner[1] + (Height - dy * 2.75), "Complete Time:")
    canvas.drawString(Corner[0] + Width + dx / 4 + (2*dx), Corner[1] + (Height - dy * 2.75), "______________")

    return Corner, Height, Width

def SecondTopRectangle(stakerWorkOrder, canvas, PreviousCorner, PreviousHeight, PreviousWidth):
    Corner=[PreviousCorner[0] + PreviousWidth, PreviousCorner[1]]
    Height = PreviousHeight * 0.72
    Width = PreviousWidth * 0.65
    canvas.rect(Corner[0], Corner[1], Width, Height)
    dx = 0.1 * reportlab.lib.units.inch
    dy = 0.15 * reportlab.lib.units.inch
    if(str(stakerWorkOrder.No_OfServicesUG) == 'None'):
        No_OfServicesUGString=''
    else:
        No_OfServicesUGString=str(stakerWorkOrder.No_OfServicesUG)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy / 2, "No. Of Services UG:  " + No_OfServicesUGString)
    if(str(stakerWorkOrder.No_OfServicesOH) == 'None'):
        No_OfServicesOHString=''
    else:
        No_OfServicesOHString=str(stakerWorkOrder.No_OfServicesOH)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 1.5, "No. Of Services OH:  " + No_OfServicesOHString)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 2.5, "General Funds")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 2.5), str(stakerWorkOrder.GeneralFundsIndicator))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 3.5, "Retire-No. Replacement")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 3.5), str(stakerWorkOrder.Retire_No_ReplacementIndicator))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 4.5, "Replacement")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 4.5), str(stakerWorkOrder.ReplacementIndicator))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 5.5, "System Improvement")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 5.5), str(stakerWorkOrder.SystemImprovementIndicator))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 6.5, "New Construction")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 6.5), str(stakerWorkOrder.NewConstructionIndicator))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 7.5, "Work Plan Reference")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 7.5), str(stakerWorkOrder.WorkPlanReferenceIndicator))
    return Corner, Height, Width

def ThirdTopRectangle(stakerWorkOrder, canvas, PreviousCorner, PreviousHeight, PreviousWidth):
    Corner=[PreviousCorner[0] + PreviousWidth, PreviousCorner[1]]
    Height=PreviousHeight * 0.75
    Width = PreviousWidth * 2
    canvas.rect(Corner[0], Corner[1], Width, Height)
    dx = 0.1 * reportlab.lib.units.inch
    dy = 0.15 * reportlab.lib.units.inch
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 0.5, "No. Of Consumers OH:               No. Of Consumers UG:")
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 1.5, "Location Next To:  " + str(stakerWorkOrder.LocationNextTo))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 2.5, "Map No:  " + str(stakerWorkOrder.MapNo))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 3.5, "Substation:  " + str(stakerWorkOrder.Substation))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 4.5, "Loan No.:  " + str(stakerWorkOrder.LoanNo))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 5.5, "Wire:" + str(stakerWorkOrder.Wire))
    canvas.drawString(Corner[0] + (Width / 2), Corner[1] + dy * 5.5, "Size:")
    return Corner, Height, Width

def FourthTopRectangle(stakerWorkOrder, canvas, PreviousCorner, PreviousHeight, PreviousWidth):
    Corner=[PreviousCorner[0] + PreviousWidth, PreviousCorner[1]]
    Height=PreviousHeight * 1.23
    Width=PreviousWidth / 3
    canvas.rect(Corner[0], Corner[1], Width, Height)
    dx = 0.1 * reportlab.lib.units.inch
    dy = 0.15 * reportlab.lib.units.inch
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * .5, "Sumter:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * .5), stakerWorkOrder.SumterCountyIndicator)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 1.5, "Kershaw:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 1.5), stakerWorkOrder.KershawCountyIndicator)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 2.5, "Richland:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 2.5), stakerWorkOrder.RichlandCountyIndicator)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 3.5, "Lexington:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 3.5), stakerWorkOrder.LexingtonCountyIndicator)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 4.5, "Orangeburg:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 4.5), stakerWorkOrder.OrangeburgCountyIndicator)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 5.5, "Calhoun:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 5.5), stakerWorkOrder.CalhounCountyIndicator)
    canvas.drawString(Corner[0] + Width / 4, Corner[1] + Height - dy, "COUNTY")
    return Corner, Height, Width

def FifthTopRectangle(stakerWorkOrder, canvas, PreviousCorner, PreviousHeight, PreviousWidth, doc):
    Corner=[PreviousCorner[0] + PreviousWidth, PreviousCorner[1]]
    Height=PreviousHeight * 1.4
    Width=PreviousWidth * 2.25
    canvas.rect(Corner[0], Corner[1], Width, Height)
    dx = 0.1 * reportlab.lib.units.inch
    dy = 0.15 * reportlab.lib.units.inch
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * .5, "NEW R/W:  ")
    CheckBox(canvas, (Corner[0] + (Width / 2) - (4.5 * dx), Corner[1] + dy * .5), stakerWorkOrder.NewR_WIndicator)
    canvas.saveState()
    if(stakerWorkOrder.R_WToBeCutIndicator):
            canvas.setFont('Times-Bold', 9)
            canvas.setStrokeColorRGB(1,0,0)
            canvas.setFillColorRGB(1,0,0)
    canvas.drawString(Corner[0] + (Width / 2) + (2 * dx), Corner[1] + dy * 4.5, "R/W to be cut:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * 4.5), stakerWorkOrder.R_WToBeCutIndicator)
    canvas.restoreState()
    canvas.drawString(Corner[0] + (Width / 2) + (2 * dx), Corner[1] + dy * 3, " Date       _______")
    canvas.drawString(Corner[0] + (Width / 2) + (2 * dx), Corner[1] + dy * 1.75, " Footage")
    canvas.drawString(Corner[0] + (Width / 2) + (2 * dx), Corner[1] + dy * .5, "EXISTING R/W:")
    CheckBox(canvas, (Corner[0] + Width - 2*dx, Corner[1] + dy * .5), stakerWorkOrder.ExistingR_WIndicator)
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 1.5, "PUPS#:  " + str(stakerWorkOrder.PUPS))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 2.5, "Co. Permit No.:  " + str(stakerWorkOrder.Co_PermitNo))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 3.5, "Released for const:  " + str(stakerWorkOrder.EngineerReleasedForConst))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 4.5, "Checked:  " + str(stakerWorkOrder.EngineerChecked))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 5.5, "Staked:  " + str(stakerWorkOrder.EngineerStaked))
    canvas.drawString(Corner[0] + dx, Corner[1] + dy * 6.5, "ENGINEER")
    canvas.line(Corner[0], Corner[1] + dy * 7.5, Corner[0] + Width, Corner[1] + dy * 7.5)
    FirstPageInfo={}
    FirstPageInfo['PAGE_HEIGHT'] = reportlab.lib.pagesizes.LEGAL[0]
    FirstPageInfo['PAGE_WIDTH'] = reportlab.lib.pagesizes.LEGAL[1]
    FirstPageInfo['SheetNumberOfLocation'] = (Corner[0] + dx, Corner[1] + dy * 8.5) 
    canvas.drawString(Corner[0] + dx, Corner[1] - dy * 3 + Height, "W.P.:" + str(stakerWorkOrder.W_P))
    canvas.drawString(Corner[0] + (Width / 2) - dx, Corner[1] - 3 * dy + Height, "N.W.P.:" + str(stakerWorkOrder.N_W_P))
    canvas.setFont('Times-Bold', 9)
    canvas.drawString(Corner[0] + dx, Corner[1] - 2 * dy + Height, "Work Order No:  " + str(stakerWorkOrder.WorkOrderNumber))
    canvas.drawString(Corner[0] + dx, Corner[1] - 4 * dy + Height, str(stakerWorkOrder.Name))
    canvas.setFont('Times-Roman', 9)
    canvas.setFillColor(reportlab.lib.colors.blue)
    canvas.drawString(Corner[0] + dx, Corner[1] - dy + Height, '(I)-Install')
    canvas.setFillColor(reportlab.lib.colors.darkred)
    canvas.drawString(Corner[0] + dx, Corner[1] - dy + Height, '                 (R)-Remove')
    canvas.setFillColor(reportlab.lib.colors.black)
    canvas.drawString(Corner[0] + dx, Corner[1] - dy + Height, '                                      (E)-Existing')
    canvas.setFillColor(reportlab.lib.colors.black)
    canvas.drawString(Corner[0] + dx, Corner[1] - dy + Height, '                                                             (FI/FR)-Future')
    canvas.setFillColor(reportlab.lib.colors.black)
    return Corner, Height, Width

def CombineLikeConductors(AssemblyList, SpanidList, SpanLengthList):
    """Adds Phase Data and Combines Like Assemblies at the same span The (I), (E), and (R) already have been assigend to the assembly at this point"""
    CombinedAssemblyList=[]
    CombinedSpanidList=[]
    CombinedSpanLengthList=[]
    CombinationsAdded=[]
    for i in range(0, len(AssemblyList)):
        CountOfCurrentAssembly=0
        for j in range(0, len(AssemblyList)):
            if(AssemblyList[i] == AssemblyList[j] and SpanidList[i] == SpanidList[j] and SpanLengthList[i] == SpanLengthList[j]):
                CountOfCurrentAssembly = CountOfCurrentAssembly + 1
        if(not ('Assembly:  ' + str(AssemblyList[i]) + 'Spanid:  ' + str(SpanidList[i]) + 'SpanLength:  ' +  str(SpanLengthList[i])) 
               in CombinationsAdded):
            CombinedAssemblyList.append(str(CountOfCurrentAssembly) + '-' + str(AssemblyList[i]))
            CombinedSpanidList.append(str(SpanidList[i]))
            CombinedSpanLengthList.append(str(SpanLengthList[i]))
            CombinationsAdded.append('Assembly:  ' + str(AssemblyList[i]) + 'Spanid:  ' + str(SpanidList[i]) + 'SpanLength:  ' +  str(SpanLengthList[i]))
    for i in range(0, len(CombinedSpanidList)):
        CurrentAssemblyNameWithExtraInformation=CombinedAssemblyList[i]
        CurrentAssemblyNameStartOffset=CurrentAssemblyNameWithExtraInformation.find('(I)-') 
        if(not CurrentAssemblyNameStartOffset == -1):  #Add the Install Phase Code Strings
            CurrentAssemblyName=CurrentAssemblyNameWithExtraInformation[CurrentAssemblyNameStartOffset + len('(I)-'):]
            CurrentSpan = Span.objects.filter(id__exact=int(CombinedSpanidList[i]))[0]
            CurrentAssemblies=Assembly.objects.filter(Span=CurrentSpan).filter(CompatibleUnit__Name=CurrentAssemblyName).filter(InstallStatus__Name='Install')
            PhaseCodeString=' [' + CurrentAssemblies[0].GetSumOfPhaseCodes(CurrentAssemblies) + ']'
            if(not (PhaseCodeString == ' []')):    
               CombinedAssemblyList[i] = CombinedAssemblyList[i] + PhaseCodeString
        CurrentAssemblyNameStartOffset=CurrentAssemblyNameWithExtraInformation.find('(E)-') 
        if(not CurrentAssemblyNameStartOffset == -1):  #Add the Existing Phase Code Strings
            CurrentAssemblyName=CurrentAssemblyNameWithExtraInformation[CurrentAssemblyNameStartOffset + len('(E)-'):]
            CurrentSpan = Span.objects.filter(id__exact=int(CombinedSpanidList[i]))[0]
            CurrentAssemblies=Assembly.objects.filter(Span=CurrentSpan).filter(CompatibleUnit__Name=CurrentAssemblyName).filter(InstallStatus__Name='Existing')
            PhaseCodeString=' [' + CurrentAssemblies[0].GetSumOfPhaseCodes(CurrentAssemblies) + ']'
            if(not (PhaseCodeString == ' []')):
                CombinedAssemblyList[i] = CombinedAssemblyList[i] + PhaseCodeString
        CurrentAssemblyNameStartOffset=CurrentAssemblyNameWithExtraInformation.find('(R)-') 
        if(not CurrentAssemblyNameStartOffset == -1):  #Add the Remove Phase Code Strings
            CurrentAssemblyName=CurrentAssemblyNameWithExtraInformation[CurrentAssemblyNameStartOffset + len('(R)-'):]
            CurrentSpan = Span.objects.filter(id__exact=int(CombinedSpanidList[i]))[0]
            CurrentAssemblies=Assembly.objects.filter(Span=CurrentSpan).filter(CompatibleUnit__Name=CurrentAssemblyName).filter(InstallStatus__Name='Remove')
            PhaseCodeString=' [' + CurrentAssemblies[0].GetSumOfPhaseCodes(CurrentAssemblies) + ']'
            if(not (PhaseCodeString == ' []')):
                CombinedAssemblyList[i] = CombinedAssemblyList[i] + PhaseCodeString
    return CombinedAssemblyList, CombinedSpanidList, CombinedSpanLengthList





class FirstPageTemplate(reportlab.platypus.PageTemplate):
    def __init__(self, **kw):
        reportlab.platypus.PageTemplate.__init__(self)
        self.id = "first"
        self.pagesize=reportlab.lib.pagesizes.landscape(reportlab.lib.pagesizes.LEGAL)
        self.frames=[reportlab.platypus.Frame(x1=reportlab.lib.units.inch * .2, y1=reportlab.lib.units.inch * 2.95, 
                     width=13.6*reportlab.lib.units.inch, height=5.45*reportlab.lib.units.inch),]
    def beforeDrawPage(self, canvas, doc):
        canvas.saveState()
        canvas.setFont('Times-Bold', 18)
        canvas.drawCentredString(self.pagesize[0]/2.0, self.pagesize[1]-.35*reportlab.lib.units.inch, "STAKING SHEET")
        canvas.drawCentredString(self.pagesize[0]/2.0, self.pagesize[1]-.60*reportlab.lib.units.inch, "TRI-COUNTY ELECTRIC CO-OP")
        canvas.drawCentredString(self.pagesize[0]/2.0, self.pagesize[1]-.85*reportlab.lib.units.inch, "S.C. 32 CALHOUN")
        canvas.setFont('Times-Roman', 9)
        Corner, Height, Width = TopLeftRectangle(doc.StakerWorkOrder, canvas) #Crew Job Briefing
        canvas.setFont('Times-Roman', 7)
        canvas.drawString(Corner[0], Corner[1] + Height + (0.1 * reportlab.lib.units.inch), "TCEC Staker 8/31/2012")  #Form # in upperleft corner
        canvas.setFont('Times-Roman', 9)
        FirstCorner=Corner
        Corner, Height, Width = SecondTopRectangle(doc.StakerWorkOrder, canvas, Corner, Height, Width) #Work Plan Reference 
        Corner, Height, Width = ThirdTopRectangle(doc.StakerWorkOrder, canvas, Corner, Height, Width) #Loan No, Substation summary
        Corner, Height, Width = FourthTopRectangle(doc.StakerWorkOrder, canvas, Corner, Height, Width) #County
        LastCorner, Height, Width = FifthTopRectangle(doc.StakerWorkOrder, canvas, Corner, Height, Width, doc) #Work Order No, Engineer
        LastCorner[0] = LastCorner[0] + Width
        LastCorner[1] = LastCorner[1] + Height
        canvas.setFont('Times-Bold', 8)    
        MiddleCorner=[0.1*reportlab.lib.units.inch, FirstCorner[1] - 0.45 * reportlab.lib.units.inch]
        Height=0.3*reportlab.lib.units.inch
        Width=self.pagesize[0] - MiddleCorner[0] * 2
        canvas.setFont('Times-Roman', 10)
        canvas.drawString(12.50 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, "Sheet No. %d of " % (doc.page))
        canvas.doForm('LastPageNumber')
        canvas.restoreState()

class ContinuationPageTemplate(reportlab.platypus.PageTemplate):
    def __init__(self):
        reportlab.platypus.PageTemplate.__init__(self)
        self.id="rest"
        self.pagesize=reportlab.lib.pagesizes.landscape(reportlab.lib.pagesizes.LEGAL)
        self.frames=[reportlab.platypus.Frame(x1=reportlab.lib.units.inch * .2, y1=reportlab.lib.units.inch * 2.95, 
                     width=13.6*reportlab.lib.units.inch, height=5.25*reportlab.lib.units.inch),]
    def beforeDrawPage(self, canvas, doc):
        canvas.saveState()
        canvas.setFont('Times-Roman', 9)
        canvas.doForm('LastPageNumber')
        canvas.drawString(12.50 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, "Sheet No. %d of " % (canvas.getPageNumber()))
        canvas.setFont('Times-Roman', 9)
        canvas.drawString(0.5 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, "Work Order No:  " + str(doc.StakerWorkOrder.WorkOrderNumber))
        canvas.setFont('Times-Roman', 9)
        canvas.drawString(2.75 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, 'Work Plan:  ' + str(doc.StakerWorkOrder.W_P))
        canvas.setFont('Times-Bold', 9)
        canvas.drawString(5 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, str(doc.StakerWorkOrder.Name))
        canvas.setFont('Times-Roman', 9)
        canvas.restoreState()

class LastPageTemplate(reportlab.platypus.PageTemplate):
    def __init__(self):
        reportlab.platypus.PageTemplate.__init__(self)
        self.id="last"
        self.pagesize=reportlab.lib.pagesizes.landscape(reportlab.lib.pagesizes.LEGAL)
        self.frames=[reportlab.platypus.Frame(x1=reportlab.lib.units.inch * .2, y1=reportlab.lib.units.inch * .2, 
                     width=12*reportlab.lib.units.inch, height=7.5*reportlab.lib.units.inch),]
    def afterDrawPage(self, canvas, doc):
        canvas.saveState()
        canvas.setFont('Times-Roman', 9)
        canvas.doForm('LastPageNumber')
        canvas.drawString(12.50 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, "Sheet No. %d of " % (canvas.getPageNumber()))
        canvas.setFont('Times-Roman', 9)
        canvas.drawString(0.5 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, "Work Order No:  " + str(doc.StakerWorkOrder.WorkOrderNumber))
        canvas.setFont('Times-Roman', 9)
        canvas.drawString(2.75 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, 'Work Plan:  ' + str(doc.StakerWorkOrder.W_P))
        canvas.setFont('Times-Bold', 9)
        canvas.drawString(5 * reportlab.lib.units.inch, 8.22*reportlab.lib.units.inch, str(doc.StakerWorkOrder.Name))
        canvas.setFont('Times-Roman', 9)
        GlobalStakerWorkOrder[0].GenerateImage(GlobalMapFileName[0])
        #canvas.drawImage('/opt/coopgis/mapserver/a.png', x=reportlab.lib.units.inch * 3, y=reportlab.lib.units.inch * .4, height = reportlab.lib.units.inch * 7.5,
        #                   width = reportlab.lib.units.inch * 7.5)

        ImageFileNameList=GlobalStakerWorkOrder[0].GetImageFileName().split('.')
        os.system('/usr/bin/convert ' + GlobalStakerWorkOrder[0].GetImageFileName() + " -background '#d2b48c' -flatten " + ImageFileNameList[0] + 'Transparent' + '.' + ImageFileNameList[1])


        canvas.drawImage(ImageFileNameList[0] + 'Transparent' + '.' + ImageFileNameList[1], x=reportlab.lib.units.inch * 3, y=reportlab.lib.units.inch * .4, height = reportlab.lib.units.inch * 7.5,
                           width = reportlab.lib.units.inch * 7.5, mask='auto' )
        canvas.restoreState()




class MyDocTemplate(reportlab.platypus.BaseDocTemplate):
    def __init__(self, filename, **kw):
        reportlab.platypus.BaseDocTemplate.__init__(self, filename, **kw)
        first = FirstPageTemplate()
        rest = ContinuationPageTemplate()
        last = LastPageTemplate()
        PA.attachToPageTemplate(first)
        PA.attachToPageTemplate(rest)
        #PA.attachToPageTemplate(last)  #Do not want to show a minimap on the last page
        self.addPageTemplates([first, rest, last])

class MyPageAccumulator(reportlab.platypus.doctemplate.PageAccumulator):
    def pageEndAction(self,canv,doc):
        StationidList=[]
        for i in self.data:
            StationidList.append(i[0])
        CurrentPage[0]=CurrentPage[0] + 1
        if(StationidList):
            ImageFileName, NearestIntersection = GenerateIndividualPageImage(StationidList)

            ImageFileNameList=ImageFileName.split('.')
            os.system('/usr/bin/convert ' + ImageFileName + " -background '#d2b48c' -flatten " + ImageFileNameList[0] + 'Transparent' + '.' + ImageFileNameList[1])

            #raise(Exception(str('/usr/bin/convert ' + ImageFileName + " -background '#d2b48c' -flatten " + ImageFileNameList[0] + 'Transparent' + '.' + ImageFileNameList[1])))
            canv.drawImage(ImageFileNameList[0] + 'Transparent' + '.' + ImageFileNameList[1], x=reportlab.lib.units.inch * 1, y=reportlab.lib.units.inch * .2, height = reportlab.lib.units.inch * 2.8,
                           width = reportlab.lib.units.inch * 4.6) #mask='auto' ,  
            canv.drawString(reportlab.lib.units.inch * 6.5, reportlab.lib.units.inch * 2.9, NearestIntersection)




PA = MyPageAccumulator('_area_map_')
StakerWorkOrderid=['None']
GlobalStakerWorkOrder=[None]
GlobalMapFileName=[None]
CurrentPage=[0]



def GenerateIndividualPageImage(Stationids):
    from djangoproject.models import geography
    FileName=djangoproject.settings.COOPGISTempImagePath
    try:
        os.mkdir(FileName)
    except:
        pass
    FileName=FileName + ''.join(Stationids) + '.png'
    Points=[]
    for i in Stationids:
        station=geography.Station.objects.filter(id=i)[0]
        if(not station.Point in Points):
            Points.append(station.Point.transform(4326, True))
    if(not Points):
        return
    MaximumX = MinimumX = Points[0].x
    MaximumY = MinimumY = Points[0].y
    for i in Points:
        if(MaximumX < i.x):
            MaximumX = i.x
        if(MinimumX > i.x):
            MinimumX = i.x
        if(MaximumY < i.y):
            MaximumY = i.y
        if(MinimumY > i.y):
            MinimumY = i.y
    if(MinimumX == MaximumX):
        MinimumX = MinimumX - .0005
        MaximumX = MaximumX + .0005
    else:
        MinimumX = MinimumX - (MaximumX - MinimumX) * 0.15
        MaximumX = MaximumX + (MaximumX - MinimumX) * 0.15
    if(MinimumY == MaximumY):
        MinimumY = MinimumY - .0005
        MaximumY = MaximumY + .0005
    else:
        MinimumY = MinimumY - (MaximumY - MinimumY) * 0.15
        MaximumY = MaximumY + (MaximumY - MinimumY) * 0.15
    CenterPoint=Point(((MinimumX + MaximumX) / 2), ((MinimumY + MaximumY) / 2), srid=4326)
    road=djangoproject.models.Road()
    Intersection=road.FindNearestIntersection(CenterPoint)
    #Dependent on the Global List StakerWorkOrderid, value 0 being the StakerWorkOrderid as a string,
    #This is set in the Create function in this module"""
    MapFileName, LayerName=COOPGIS_Misc.GenerateDynamicMapFile(djangoproject.settings.COOPGISStakerApplicationName, UserName='',
                                                               MapReportIdentifier=StakerWorkOrderid[0])
    reportPageNumberPolygon=djangoproject.models.ReportPageNumberPolygon()
    reportPageNumberPolygon.Create(MinimumX, MinimumY, MaximumX, MaximumY, srid=4326, Name='StakerReportMiniMap', 
                                   MapReportIdentifier=StakerWorkOrderid[0], Page=str(CurrentPage[0]))
    TempPoint = Point(MinimumX, MinimumY, srid=4326)
    ConvertedPoint = TempPoint.transform(3857, clone=True)
    ConvertedMinimumX = ConvertedPoint.x
    ConvertedMinimumY = ConvertedPoint.y

    TempPoint = Point(MaximumX, MaximumY, srid=4326)
    ConvertedPoint = TempPoint.transform(3857, clone=True)
    ConvertedMaximumX = ConvertedPoint.x
    ConvertedMaximumY = ConvertedPoint.y

   
    ImageFileNameOption=' -o ' + FileName
    #MapFileNameOption = ' -m ' + MapFileName
    MapFileNameOption = ' -m ' + GlobalMapFileName[0]
    #raise(str(MapFileNameOption))

    ExtentsOption = ' -e ' + str(ConvertedMinimumX) + ' ' + str(ConvertedMinimumY) + ' ' + str(ConvertedMaximumX) + ' ' + str(ConvertedMaximumY)
    
    os.system('sudo -u apachescript sudo /usr/bin/shp2img' + MapFileNameOption + ImageFileNameOption + ExtentsOption)
    #raise(Exception(str('sudo -u apachescript sudo /usr/bin/shp2img' + MapFileNameOption + ImageFileNameOption + ExtentsOption)))
   
    return FileName, Intersection


def GetImageFileName(self):
    return djangoproject.settings.COOPGISStakerWorkOrderReportPath + str(self.id) + '.png'
